package com.gsafety.wellsfort.config;

import com.gsafety.wellsfort.common.constant.IConstant;
import com.gsafety.wellsfort.common.context.LoginContext;
import com.gsafety.wellsfort.common.context.LoginContextUtil;
import com.gsafety.wellsfort.common.util.IpUtil;
import com.gsafety.wellsfort.dao.security.UserLoginDAO;
import com.gsafety.wellsfort.domain.model.organization.Student;
import com.gsafety.wellsfort.domain.model.security.Admin;
import com.gsafety.wellsfort.domain.model.security.UserLogin;
import com.gsafety.wellsfort.service.security.IUserLoginService;
import com.owlike.genson.Genson;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Optional;

/**
 * 请求拦截器
 *
 * @author 1
 */
@Aspect
@Component
public class WebLogAspect {
    @Resource
    private RedisTemplate<Object, Object> redisTemplate;
    @Autowired
    private IUserLoginService userLoginService;
    private static final Logger logger = LoggerFactory.getLogger(WebLogAspect.class);

    @Pointcut("execution(public * com.gsafety.wellsfort.controller.*.*.*(..)) ")
    public void logPointCut() {
    }

    @Before("logPointCut()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        // 接收到请求，记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        // 记录下请求内容
        logger.info("========================= aop log start=========================");
        String urlKey = request.getRequestURI().toString() + "\t";
        logger.info(urlKey + "请求地址 : " + request.getRequestURL().toString());
        logger.info(urlKey + "HTTP METHOD : " + request.getMethod());
        logger.info(urlKey + " token : " + request.getHeader(IConstant.TOKEN));
        logger.info(urlKey + "IP : " + IpUtil.getIp(request));
        logger.info(urlKey + "CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "."
                + joinPoint.getSignature().getName());
        logger.info(urlKey + "参数 : " + Arrays.toString(joinPoint.getArgs()));
        logger.info(urlKey + "设备信息 : " + request.getHeader(IConstant.DEVICE_ID));
        logger.info(urlKey + "设备系统  : " + request.getHeader(IConstant.PLANT_FORM));
        MDC.put("urlKey", urlKey);

        /**
         *      在用户登录时,获取设备信息,并且将设备信息 来源(android||ios存入org_user_login表)
         *      将设备id和ios存入org_user_login表 id 绑定,用户注销时退出绑定
         */
        String deviceId = request.getHeader(IConstant.DEVICE_ID);
        String plantForm = request.getHeader(IConstant.PLANT_FORM);
        Student student=LoginContextUtil.getStudent();
        if(student!=null){
            if (Optional.ofNullable(deviceId).isPresent() && Optional.ofNullable(plantForm).isPresent()) {
                UserLogin userLogin = UserLogin.builder().ext2(plantForm).ext3(deviceId).id(LoginContextUtil.getUid()).build();
                userLoginService.bindUserInfo(userLogin);
            }
        }
    }

    @AfterReturning(returning = "ret", pointcut = "logPointCut()") // returning的值和doAfterReturning的参数名一致
    public void doAfterReturning(Object ret) throws Throwable {

        logger.info(MDC.get("urlKey") + "返回值 : " + new Genson().serialize(ret));
        logger.info("========================= aop log end=========================");
    }
}